const { containerConfig } = require('../config');
const { waitQueue, finishQueue, sleep } = require('../utils/WVTools');
const rp = require('request-promise');

/* eslint no-console:0 */
//
// Demonstrate some of the basics.

// import { get } from 'https';

//
const Client = require('kubernetes-client').Client;
const client = new Client({ version: '1.9' });


async function get_ips() {
    /* Get all the ns3 service. */
    try {
        const service = await client.api.v1.namespaces('default').pods().get();
        items = service.body.items;
        console.log('items: ', items);
        ns3_items = items.filter(item => item.metadata.labels.app == 'node-ns3' && item.status.phase == 'Running');
        ips = ns3_items.map(item => item.status.podIP);
        console.log('ips: ', ips);
        return ips;
    } catch (err) {
        console.error('Error: ', err);
    }
}

async function set_ns3_num(num) {
    /*  Change the ns3 Deployment Replica count */
    try {
        const replica = {
            spec: {
                replicas: num
            }
        };
        const replicaModify = await client.apis.apps.v1.namespaces('default').deployments('node-ns3').patch({ body: replica });
        console.log(replicaModify);
    } catch (err) {
        console.error('Error: ', err);
    }
}

const containerManager = {
  // getAFreeContainer (number) {
  //   const waitReq = waitQueue.length;
  //   if (waitReq > 0) { // 队列非空
  //     const curOrder = waitQueue.indexOf(number);
  //     if (curOrder > 0 ) { // 已在队列中且不是第一个
  //       return 'notHead';
  //     } if (curOrder == -1) { // 不在队列中
  //       waitQueue.push(number);
  //       return 'notHead';
  //     }
  //   }
  //   let i = 0;
  //   for (i = 0; i < containerConfig.number; i += 1) {
  //     if (!containerConfig.containersList[i].isBusy) {
  //       break;
  //     }
  //   }
  //   if (i < containerConfig.number) {
  //     containerConfig.containersList[i].isBusy = true;
  //     if (waitQueue.length > 0) { // 由队首来
  //       waitQueue.shift();
  //     }
  //     return containerConfig.containersList[i];
  //   }
  //   if (waitQueue.length == 0) { // 该请求不是在队首
  //     waitQueue.push(number);
  //   }
  //   return 'head';
  // },
  getAFreeContainer () {
    for(let i = 0; i < containerConfig.curNumber; i++) {
      if (containerConfig.containersList[i].isBusy == false) {
        containerConfig.containersList[i].isBusy = true;
        return containerConfig.containersList[i];
      }
    }
    return null;
  },

  intoQueue (number, code) {
    waitQueue.push({number, code});
    if (waitQueue.length == 1) {
      this.sendCode();
    }
    if (waitQueue.length > containerConfig.curNumber && containerConfig.curNumber < containerConfig.totalNumber) { //满足扩容条件
      containerConfig.curNumber += 1;
      this.sendCode();
    }
  },

  async sendCode () {
    const container = this.getAFreeContainer();
    if (!container) {
      return;
    }
    const forwardResult = {
      suc: true
    };
    const moreInfo = {
      containerOrder: container.order,
      containerHost: container.host
    };
    const { number, code } = waitQueue.shift();
    const options = {
      method: 'POST',
      uri: `http://${container.host}:${container.port}${container.api}`,
      form: {code}
    };
    const startTime = Date.now();
    const responseJSON = await rp(options)
      .catch((err) => {
        forwardResult.suc = false;
        forwardResult.err = err;
      });
    if (forwardResult.suc) {
      if (!responseJSON || responseJSON == 'undefined') {
        forwardResult.suc = false;
        forwardResult.err = 'service inside docker killed!';
      } else {
        forwardResult.response = JSON.parse(responseJSON);
        moreInfo.endTime = Date.now();
        moreInfo.startTime = startTime;
        moreInfo.time = moreInfo.endTime - moreInfo.startTime;
      }
    }
    finishQueue.push({number, forwardResult, moreInfo});
    this.free(container.order);
    if (waitQueue.length < containerConfig.curNumber && containerConfig.curNumber > 1) {
      containerConfig.curNumber -= 1;
    }
    if (waitQueue.length > 0) {
      await this.sendCode();
    }
  },

  free (order) {
    containerConfig.containersList[order].isBusy = false;
  },

  async containersInit () {
    // await set_ns3_num(containerConfig.number);
    // await sleep(10000);
    // const ipList = await get_ips();
    for (let i = 0; i < containerConfig.totalNumber; i += 1) {
      const container = {
        order: i,
        isBusy: false,
        host: `web${i + 1}`,
        port: containerConfig.port,
        api: '/run'
      }
      containerConfig.containersList.push(container);
      console.log(container);
    }
  },

  getRunState (number) {
    for(let i = 0; i < waitQueue.length; i += 1) {
      if (waitQueue[i].number == number) {
        return 'waiting';
      }
    }
    for(let i = 0; i < finishQueue.length; i += 1) {
      if (finishQueue[i].number == number) {
        return 'finished';
      }
    }
    return 'runing';
  },

  getResponseInfo (number) {
    for(let i in finishQueue) {
      if (finishQueue[i].number == number) {
        const { forwardResult, moreInfo } = finishQueue[i];
        finishQueue.splice(i, 1);
        return { forwardResult, moreInfo };
      }
    }
  }
}

module.exports = {
  containerManager
};
